/*
 *  +----------------------------------------------------------------------
 *  | sophon [ A FAST GAME FRAMEWORK ]
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2023-2029 All rights reserved.
 *  +----------------------------------------------------------------------
 *  | Licensed ( http:www.apache.org/licenses/LICENSE-2.0 )
 *  +----------------------------------------------------------------------
 *  | Author: jqiris <1920624985@qq.com>
 *  +----------------------------------------------------------------------
 */

use chrono::{DateTime, NaiveDateTime, TimeZone};
use serde::{Deserialize, Deserializer, Serializer};

pub fn serialize<S>(dt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
{
    match dt {
        None => { serializer.serialize_none() }
        Some(d) => {
            let cst_time = chrono::FixedOffset::east_opt(8 * 3600).unwrap().from_local_datetime(&d).unwrap();
            let s = cst_time.to_rfc3339();
            serializer.serialize_str(&s)
        }
    }
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<NaiveDateTime>, D::Error>
    where
        D: Deserializer<'de>,
{
    let sd = String::deserialize(deserializer);
    match sd {
        Ok(s) => {
            if s.is_empty() || s == "0001-01-01T00:00:00Z" {
                Ok(None)
            } else {
                let dt = DateTime::parse_from_rfc3339(&s).map_err(serde::de::Error::custom)?;
                Ok(Some(dt.naive_local()))
            }
        }
        Err(_err) => {
            Ok(None)
        }
    }
}